using System;
using System.Collections.Generic;
using System.Text;

namespace Forecast.Domain.Implementation
{
    public class Wallet : ICountMoney
    {
        #region Variables

        private int _availableCash;
        private int _cashSetAsideForOffers;

        #endregion 
        #region Constructors

        public Wallet() {}

        #endregion
        #region Interface

        public void SetCashAsideForOffer(int offerValue)
        {
            if (offerValue < 0)
                throw new ArgumentException("Tried to set aside a negative amount.");
            if (offerValue > AvailableCash)
                throw new ApplicationException(
                    String.Format("Tried to set aside too much cash for an offer. "
                    + "Only have {0} to set aside, but tried to set aside {1}.",
                    AvailableCash,
                    offerValue));

            _availableCash -= offerValue;
            _cashSetAsideForOffers += offerValue;
        }

        public void AdjustForOfferAccepted(int cash)
        {
            if (cash < 0)
                throw new ArgumentException("Tried to adjust for a negative amount.");
            if (cash > CashSetAsideForOffers)
                throw new ApplicationException(
                    String.Format("Tried to adjust for an accepted offer for more than was set aside. "
                    + "Only {1} was set aside, but tried to adjust for {1}.",
                    CashSetAsideForOffers,
                    cash));

            _cashSetAsideForOffers -= cash;
        }

        public void AdjustForOfferCancelled(int cash)
        {
            if (cash < 0)
                throw new ArgumentException("Tried to adjust for a negative amount.");
            if (cash > CashSetAsideForOffers)
                throw new ApplicationException(
                    String.Format("Tried to adjust for a cancelled offer for more than was set aside. "
                    + "Only {1} was set aside, but tried to adjust for {1}.",
                    CashSetAsideForOffers,
                    cash));

            _cashSetAsideForOffers -= cash;
            _availableCash += cash;
        }

        public void AddCash(int cash)
        {
            if (cash < 0)
                throw new ArgumentException("Tried to add a negative amount.", "cash");

            _availableCash += cash;
        }

        public void RemoveCash(int cash)
        {
            if (cash < 0)
                throw new ArgumentException("Tried to remove a negative amount.", "cash");
            if (cash > _availableCash)
                throw new ApplicationException(String.Format(
                    "There is not enough cash. Tried to remove {0}, but only have {1}",
                    cash.ToString(),
                    _availableCash.ToString()));

            _availableCash -= cash;
        }

        #endregion
        #region Properties

        public int CashSetAsideForOffers
        {
            get { return _cashSetAsideForOffers; }
        }

        public int AvailableCash 
        {
            get { return _availableCash; }
        }

        public int TotalWorth
        {
            get { return AvailableCash + CashSetAsideForOffers; }
        }

        #endregion
    }
}
